﻿package bdz.pv3d.extensions{
	
	import flash.display.Sprite;
	import flash.filters.BlurFilter;
	import org.papervision3d.core.*;
	import org.papervision3d.core.geom.*;
	import bdz.pv3d.extensions.utils.Line3DSegment;
	import org.papervision3d.core.proto.*;
	import org.papervision3d.objects.DisplayObject3D;
	
	
	public class Line3D extends Vertices3D
	{
		
		
		public var segments:Array;
		public var scaled:Boolean;
		public var _alpha:Number;
		
		public function Line3D(vertices:Array, alpha:Number = 1, scaled:Boolean = true)
		{
			super(null, null, null);
			segments = new Array();
			this.scaled = scaled;
			this._alpha = alpha;
			this.geometry.vertices = new Array();
			//super(vertices, null, null);
			for each(var v:Vertex3D in vertices){
				addVertex(v);
			}
		}
		
		public override function project( parent :DisplayObject3D, camera :CameraObject3D, sorted :Array=null ):Number
		{
				//var screenZ:Number =
				super.project( parent, camera, sorted );

				var view:Matrix3D = this.view,

				// Camera
				m11 :Number = view.n11,
				m12 :Number = view.n12,
				m13 :Number = view.n13,
				m21 :Number = view.n21,
				m22 :Number = view.n22,
				m23 :Number = view.n23,
				m31 :Number = view.n31,
				m32 :Number = view.n32,
				m33 :Number = view.n33,
				vx	:Number,
				vy	:Number,
				vz	:Number,
				s_x	:Number,
				s_y	:Number,
				s_z	:Number,
				vertex:Vertex3D, 
				screen:Vertex2D,
				persp :Number,

				vertices :Array  = this.geometry.vertices,
				i        :int    = 0,

				focus    :Number = camera.focus,
				fz       :Number = focus * camera.zoom,
				dPersp	:Number = 0;
				
				
				while( i < vertices.length )
				{
					
					vertex = vertices[i];
					// Center position
					vx = vertex.x;
					vy = vertex.y;
					vz = vertex.z;
					
					s_z = vx * m31 + vy * m32 + vz * m33 + view.n34;
					persp = fz / (focus + s_z);
					screen = vertex.vertex2DInstance;
			
					if( screen.visible = ( s_z > 0 ) )
					{
						s_x = vx * m11 + vy * m12 + vz * m13 + view.n14;
						s_y = vx * m21 + vy * m22 + vz * m23 + view.n24;
						
						
						screen.x = s_x * persp;
						screen.y = s_y * persp;
						screen.z = s_z;
						
					}
					
					if(i > 0){				
						
						//average out the persp.
						segments[i-1].scaledSize = (segments[i-1].size*((persp+dPersp)/2));
					}
					dPersp = persp;
					
					i++;
				}

				return 0; //screenZ;
		
		}
		
		
		
		public function addVertex(v:Vertex3D, lineProps:Object = null):Line3DSegment{
			
			if(this.geometry.vertices.length == 0){
				this.geometry.vertices.push(v);
			}else{
			
				var lv:Vertex3D = this.geometry.vertices[this.geometry.vertices.length-1];
				this.geometry.vertices.push(v);
				var seg:Line3DSegment = new Line3DSegment(lv, v, lineProps);
				segments.push(seg);
				
			
			}
			return seg;
			
		}
		public function removeVertex():Vertex3D {
			segments.shift();
			return this.geometry.vertices.shift();
			
		}
		
		public function get vertex():Array {
			return this.geometry.vertices;
		}
		
		public function render(scene:SceneObject3D ):void
		{
			
			var container:Sprite = this.container || scene.container;
			if(this.container){
				container.graphics.clear();
			}
			
			for each(var ls:Line3DSegment in segments){
				ls.render(container, scaled, alpha);
			}

		}
		
	}
}
